﻿#pragma once
#include <unordered_map>


template<class KEY, class VALUE>
class ShareHashMap
{
public:
	typedef std::unordered_map<KEY, VALUE> BaseMap;
	typedef typename std::unordered_map<KEY, VALUE>::iterator Iter;
	typedef typename std::unordered_map<KEY, VALUE>::const_iterator ConstIter;

	explicit ShareHashMap() {}

	size_t size()
	{
		sMutex_.lock_shared();
		size_t s = shareMap_.size();
		sMutex_.unlock_shared();
		return s;
	}

	void swap(ShareHashMap<KEY, VALUE> &other)
	{
		sMutex_.lock();
		shareMap_.swap(other.shareMap_);
		sMutex_.unlock();
	}

	//线程不安全
	VALUE &operator[](const KEY &key)
	{
		sMutex_.lock_shared();
		VALUE &val = shareMap_[key];
		sMutex_.unlock_shared();
		return val;
	}

	VALUE operator[](const KEY &key)
	{
		sMutex_.lock_shared();
		VALUE val = shareMap_[key];
		sMutex_.unlock_shared();
		return val;
	}

	//线程不安全
	const VALUE &operator[](const KEY &key)const
	{
		sMutex_.lock_shared();
		VALUE &val = shareMap_[key];
		sMutex_.unlock_shared();
		return val;
	}

	int bind(KEY key, VALUE &value)
	{
		std::lock_guard<std::shared_mutex> lock(sMutex_);
		if (this->shareMap_.insert({ key, value }).second == false)
			return -1;
		return 0;
	}

	void remove(KEY key)
	{
		sMutex_.lock();
		shareMap_.erase(key);
		sMutex_.unlock();
	}

	//线程不安全
	Iter find(KEY key)
	{
		sMutex_.lock_shared();
		ShareHashMap<KEY, VALUE>::Iter it = shareMap_.find(key);
		sMutex_.unlock_shared();
		return it;
	}

	bool find(KEY key, VALUE &val)
	{
		sMutex_.lock();
		Iter it = shareMap_.find(key);
		if (it == end())
		{
			sMutex_.unlock();
			return false;
		}

		val = it->second;
		sMutex_.unlock();
		return true;
	}

protected:
	Iter begin()
	{
		return shareMap_.begin();
	};

	ConstIter begin()const
	{
		return shareMap_.begin();
	}

	Iter end()
	{
		return shareMap_.end();
	}

	ConstIter end()const
	{
		return shareMap_.end();
	}

private:
	BaseMap shareMap_;
	std::shared_mutex sMutex_;
};


